package chapter2;

public class LinkedList implements Cloneable {
    private Object field;
    private LinkedList next;
    
    public LinkedList clone(){
        try{
            LinkedList startPoint = this;
            LinkedList nObj = (LinkedList)super.clone();
            //initialize the new object
            nObj.field = null;
            nObj.next = null;
            
            while(startPoint.next != null && startPoint.next != this){
                nObj.push(startPoint.next.field);
                startPoint = startPoint.next;
            }
            return nObj;
        }catch(CloneNotSupportedException e){
            return null;
        }
    }
    
    public LinkedList(){
    }
    
    public LinkedList(Object obj){
        this.field = obj;
    }
    
    public void push(Object obj){
        LinkedList nEle = new LinkedList(obj);
        nEle.next = this.next;
        this.next = nEle;
    }
    
    /**
     * Interesting!!! linked list is a loop list that the next element of last element is header.
     * the previous element of header is the last element
     * @return
     */
    int size(){
        int size = 1;
        LinkedList startPoint = this;
        
        while(startPoint.next != null && startPoint.next != this){
            size += 1;
            startPoint = startPoint.next;
        }
        return size;
    }
    
    public String toString(){
        String desc = "field: " + field.toString();
        if(next != null){
            desc += "next is " + next.toString();
        }
        return desc;
    }
    
    public static void main(String[] args){
        Vehicle bus = new Vehicle("me");
        Vehicle bicycle = new Vehicle("apple");
        Vehicle jeep = new Vehicle("jeep");
        
        LinkedList alist = new LinkedList();
        alist.push(bus);
        alist.push(bicycle);
        
        
        System.out.println(alist.size());
        
        //clone this list
        LinkedList blist = alist.clone();
        blist.push(jeep);
        
        System.out.println(blist.size());
        System.out.println(alist.size());
        
    }
}
